package com.tywj.panda.customer.common.view.base

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import java.util.*

/**
 * <pre>
 *     author : June Yang
 *     time   : 2020/5/8
 *     desc   : fragment切换管理器
 *     version: 1.0.0
 * </pre>
 */
class FragmentChangeManager(
    private val fragmentManager: FragmentManager,
    private val containerViewId: Int,
    private val fragments: ArrayList<Fragment>,
    private val tags: ArrayList<String> = ArrayList(),
    /**
     * 第一个可见的Fragment索引，默认是第一个。
     * 如果初始化的时候不打算显示任何一个Fragment，则传入[INDEX_HIDE_ALL]。
     */
    private val firstVisibleFragmentIndex: Int = 0
) {

    companion object {
        /**
         * 隐藏所有的Fragment
         */
        const val INDEX_HIDE_ALL = -1
    }

    /**
     * 设置或获取当前显示的Fragment索引。
     * 设置的时候，如果设置为[INDEX_HIDE_ALL]则隐藏所有的Fragment，不显示任何Fragment。
     * 获取的时候，如果值为[INDEX_HIDE_ALL]，则当前没有显示任何一个Fragment。
     */
    var currentFragmentIndex = INDEX_HIDE_ALL
        set(value) {
            if (field != value) {
                if (value in fragments.indices || value == INDEX_HIDE_ALL) {
                    changeVisibleFragment(value)
                    field = value
                } else {
                    throw IllegalArgumentException("Wrong Index!")
                }
            }
        }

    /**
     * 获取当前显示的Fragment，如果所有的Fragment都处于隐藏状态，则返回null
     */
    val currentFragment: Fragment?
        get() = if (currentFragmentIndex in fragments.indices) fragments[currentFragmentIndex] else null

    init {
        initFragments()
    }

    private fun initFragments() {
        when {
            tags.isEmpty() -> {
                for (fragment in fragments) {
                    val ft = fragmentManager.beginTransaction()
                    if (!fragment.isAdded) {
                        ft.add(containerViewId, fragment)
                    }
                    ft.hide(fragment).commitAllowingStateLoss()
                }
            }
            fragments.size != tags.size -> {
                throw IllegalArgumentException("tag size must equals fragment size!")
            }
            else -> {
                fragments.forEachIndexed { index, fragment ->
                    val ft = fragmentManager.beginTransaction()
                    if (!fragment.isAdded) {
                        ft.add(containerViewId, fragment, tags[index])
                    }
                    ft.hide(fragment).commitAllowingStateLoss()
                }
            }
        }

        currentFragmentIndex = firstVisibleFragmentIndex
    }

    private fun changeVisibleFragment(index: Int) {
        for (i in fragments.indices) {
            val ft = fragmentManager.beginTransaction()
            val fragment = fragments[i]
            if (i == index) {
                ft.show(fragment)
            } else {
                ft.hide(fragment)
            }
            ft.commitAllowingStateLoss()
        }
    }
}